package top.onedream.buildsmallsoftware.cfg

import com.fasterxml.jackson.annotation.JsonAutoDetect
import com.fasterxml.jackson.annotation.PropertyAccessor
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.core.RedisTemplate
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
import org.springframework.data.redis.serializer.StringRedisSerializer
import java.io.Serializable

/**
 * @Description: redis 配置
 * @Author: junqiang.lu
 * @Date: 2018/10/29
 */
@Configuration
class RedisConfig(private val objectMapper: ObjectMapper) {
    /**
     * redisTemplate 序列化默认使用的jdk Serializable, 存储二进制字节码, 所以自定义序列化类
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    fun redisTemplate(redisConnectionFactory: RedisConnectionFactory?): RedisTemplate<Serializable, Any> {
        val redisTemplate = RedisTemplate<Serializable, Any>()
        redisTemplate.setConnectionFactory(redisConnectionFactory!!)
        // 使用Jackson2JsonRedisSerialize替换默认序列化
        val jackson2JsonRedisSerializer: Jackson2JsonRedisSerializer<*> = Jackson2JsonRedisSerializer(
            Any::class.java
        )
        val objectMapper = objectMapper.copy()
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY)
        objectMapper.activateDefaultTyping(
            LaissezFaireSubTypeValidator(),
            ObjectMapper.DefaultTyping.EVERYTHING
        )
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper)
        // 设置value的序列化规则和key的序列化规则
        redisTemplate.keySerializer = StringRedisSerializer()
        redisTemplate.hashKeySerializer = StringRedisSerializer()
        redisTemplate.valueSerializer = jackson2JsonRedisSerializer
        redisTemplate.hashValueSerializer = jackson2JsonRedisSerializer
        redisTemplate.afterPropertiesSet()
        return redisTemplate
    }
}
